package com.jxmcloud.business.cut.service.impl.app.live;

import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.jxmcloud.business.cut.constants.CutConstants;
import com.jxmcloud.business.cut.constants.CutErrorMsg;
import com.jxmcloud.business.cut.dto.client.DrawMoneyLogListDto;
import com.jxmcloud.business.cut.dto.client.GetLiveWatchAwardDto;
import com.jxmcloud.business.cut.dto.client.GetLiveWatchStateDto;
import com.jxmcloud.business.cut.dtoCommon.WithdrawLog;
import com.jxmcloud.business.cut.json.DataConfigService;
import com.jxmcloud.business.cut.mapper.database.IUserGainAwardRecordDBMapper;
import com.jxmcloud.business.cut.mapper.database.IUserWatchLiveTaskDetailDBMapper;
import com.jxmcloud.business.cut.model.database.DBUserActivityInfo;
import com.jxmcloud.business.cut.model.database.DBUserDrawMoneyLog;
import com.jxmcloud.business.cut.model.database.DBUserWatchLiveTaskDetail;
import com.jxmcloud.business.cut.service.app.live.ILiveService;
import com.jxmcloud.business.cut.service.database.IUserActivityInfoDBService;
import com.jxmcloud.business.cut.service.database.IUserDrawMoneyLogDBService;
import com.jxmcloud.business.cut.service.database.IUserGainAwardRecordDBService;
import com.jxmcloud.business.cut.service.logic.IUserLiveHandle;
import com.jxmcloud.business.cut.util.MyTool;
import com.jxmcloud.business.cut.vo.client.DrawMoneyLogListVo;
import com.jxmcloud.business.cut.vo.client.GetLiveWatchAwardVo;
import com.jxmcloud.business.cut.vo.client.GetLiveWatchStateVo;
import com.jxmcloud.business.cut.vo.json.ConfigStartVo;
import com.jxmcloud.business.cut.vo.user.PlayerInfoVo;
import com.jxmcloud.business.cut.vo.user.UserBaseVo;
import com.xlcloud.platform.api.exception.BusinessException;
import com.xlcloud.platform.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class LiveServiceImpl implements ILiveService {
    @Autowired
    private IUserWatchLiveTaskDetailDBMapper userWatchLiveTaskDetailMapper;
    @Autowired
    private IUserLiveHandle userLiveHandle;
    @Autowired
    private IUserActivityInfoDBService userActivityInfoDBService;
    @Autowired
    private IUserGainAwardRecordDBMapper userGainAwardRecordDBMapper;
    @Autowired
    private IUserGainAwardRecordDBService userGainAwardRecordDBService;
    @Autowired
    private IUserDrawMoneyLogDBService userDrawMoneyLogDBService;
    @Autowired
    private DataConfigService dataConfigService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GetLiveWatchAwardVo GetLiveWatchAward(GetLiveWatchAwardDto dto, PlayerInfoVo player) {
        String error = CutErrorMsg.ERROR_TRUE;
        GetLiveWatchAwardVo result = new GetLiveWatchAwardVo();
        do {
            UserBaseVo base = player.getBase();
            // 1. check 用户活动是否存在
            DBUserActivityInfo dbUserActivityInfo = userActivityInfoDBService.selectByUidAndActivityIdOnDoing(base.getUid());
            if (dbUserActivityInfo.getStatus() != 0) {
                error = "当前活动不存在!";
                break;
            }

            // 新增不领取奖励，只是扫脸
            if (!dto.getIsGain()) {
                dbUserActivityInfo.setImageUrl(dto.getImageUrl());
                if (userActivityInfoDBService.updateData(dbUserActivityInfo)) {
                    break;
                }
            }

            // 2. 设置用户活动数据
            dbUserActivityInfo.setStatus(1);
            dbUserActivityInfo.setGainPrize(1);
            dbUserActivityInfo.setImageUrl(dto.getImageUrl());
            boolean flag = userActivityInfoDBService.updateData(dbUserActivityInfo);
            if (!flag) {
                error = "设置用户活动数据失败!";
                break;
            }

            // 3. 给用户发放奖励
            flag = userGainAwardRecordDBService.insertIntoData(player);
            if (!flag) {
                error = "发放奖励失败!";
                break;
            }

            // 4. 记录用户领取奖励日志
            Integer startId = player.getActivity().getStartId();
            Integer activityId = player.getActivity().getActivityId();
            Integer money = 0;
            ConfigStartVo configStartVo = dataConfigService.getConfigStartConfig(startId);
            if (ObjectUtil.isNotNull(configStartVo)) {
                money = configStartVo.getGold();
            }
            DBUserDrawMoneyLog dbLog = new DBUserDrawMoneyLog();
            dbLog.setUid(base.getUid());
            dbLog.setMoney(money);
            dbLog.setAccount(base.getAccount());
            dbLog.setActivityId(activityId);
            dbLog.setAddTime(new Date());
            userDrawMoneyLogDBService.insertData(dbLog);
        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
        return result;
    }

    // 获取观看直播是否完成
    @Override
    public GetLiveWatchStateVo GetLiveWatchState(GetLiveWatchStateDto dto, PlayerInfoVo player) {
        String error = CutErrorMsg.ERROR_FALSE;
        GetLiveWatchStateVo result = new GetLiveWatchStateVo();
        do {
            DBUserActivityInfo dbUserActivityInfo = userActivityInfoDBService.selectByUidAndActivityIdOnDoing(player.getBase().getUid());

            // 1. init初始化直播数据
            DBUserWatchLiveTaskDetail userWatchLiveTaskDetail = userLiveHandle.createUserWatchLiveTaskDetail(player);

            // 2. 获取用户观看直播达标的天数
            // 观看直播开始时间
            String startDay = DateUtil.formatDate(userWatchLiveTaskDetail.getCreateTime());
            // 观看直播结束时间
            String endDay = DateUtil.formatDate(new Date());
            // 查询用户达标天数
            Integer watchLiveDays = userLiveHandle.getWatchLiveDays(player, startDay, endDay);
            // 3. GM功能根据设置达标天数来模拟用户真正达标天数
            Integer conditionDays = userLiveHandle.getWatchLiveDaysByCondition(userWatchLiveTaskDetail, 1);
            watchLiveDays = watchLiveDays >= conditionDays ? watchLiveDays : conditionDays;
            // 4. 判断直播任务是否完成
            boolean flag = userLiveHandle.judgeIsFinishWatchLive(watchLiveDays, 1);
            if (flag) {
                userWatchLiveTaskDetail.setStatus(1);
                dbUserActivityInfo.setWatchLive(1);
                userActivityInfoDBService.updateData(dbUserActivityInfo);
                userWatchLiveTaskDetailMapper.updateById(userWatchLiveTaskDetail);
            }

            // 4. 返回数据
            result.setState(userWatchLiveTaskDetail.getStatus());
            result.setWatchDays(watchLiveDays);
            result.setImageUrl(dbUserActivityInfo.getImageUrl() == null ? "" : dbUserActivityInfo.getImageUrl());

            error = CutErrorMsg.ERROR_TRUE;
        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
        return result;
    }

    @Override
    public DrawMoneyLogListVo drawMoneyLogList(DrawMoneyLogListDto dto, PlayerInfoVo player) {
        String error = CutErrorMsg.ERROR_TRUE;
        DrawMoneyLogListVo result = new DrawMoneyLogListVo();
        do {
            // Integer uid = player.getBase().getUid();
            String account = player.getBase().getAccount();
            List<DBUserDrawMoneyLog> dbUserDrawMoneyLogs = userDrawMoneyLogDBService.selectLastN(account, CutConstants.LOG_COUNT_DRAW_MONEY);
            List<WithdrawLog> list = Lists.newArrayList();
            for (DBUserDrawMoneyLog dbUserDrawMoneyLog : dbUserDrawMoneyLogs) {
                WithdrawLog withdrawLog = new WithdrawLog();
                Long addTime = MyTool.toTimeByDate(dbUserDrawMoneyLog.getAddTime());
                withdrawLog.setTime(addTime.intValue());
                withdrawLog.setMoney(dbUserDrawMoneyLog.getMoney());
                list.add(withdrawLog);
            }
            result.setList(list);
        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
        return result;
    }
}
